﻿#include "QBaseLog.h"

#include <QFile>
#include <QDir>
#include <QDateTime>
#include <QList>
#include <QMutex>
#include <QDebug>


static QBaseLog* message;
QMutex QBaseLog::mutex;
QFile QBaseLog::fileLog;
QString QBaseLog::logFilePath;
QStringList QBaseLog::listLogMsg;
QStringList QBaseLog::mapMsgType = { "QtDebugMsg","QtWarningMsg","QtCriticalMsg","QtFatalMsg","QtInfoMsg" };

bool QBaseLog::open_sys_message(QString path)
{
    if (logFilePath == path)
    {
        qDebug() << QStringLiteral("=======日志文件已经被打开=======");
        return false;
    }
    //判断目录是否存在
    QDir dir(path);
    if (!dir.exists())
    {
        dir.mkdir(path);
    }

    //打开文件
    logFilePath = path;
    QString file_name = QString("%1/%2%3").arg(logFilePath).arg(QDate::currentDate().toString("yyyy-MM-dd")).arg(QString(".log"));
    fileLog.setFileName(file_name);
    if (!fileLog.open(QIODevice::WriteOnly | QIODevice::Append))
    {
        qDebug() << QStringLiteral("=======打开日志文件失败=======");
        return false;
    }

    if (!message)
        message = new QBaseLog;
    message->start(QThread::LowestPriority);
    message->isRunning = true;

    return true;
}

void QBaseLog::close_sys_message()
{
    if (message != nullptr)
    {
        //取消重定向
        qInstallMessageHandler(Q_NULLPTR);
        //等待日志全部写入到文件中
        while (listLogMsg.count());
        //退出日志线程
        message->isRunning = false;
        message->quit();
        message->wait();
        if (fileLog.isOpen())
            fileLog.close();
        delete message;
        message = nullptr;
    }
}

void QBaseLog::SysMessageOutput(QtMsgType type, const QMessageLogContext& context, const QString& msg)
{
    QString strDateTime = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz");

    if (type == QtMsgType::QtDebugMsg || type == QtMsgType::QtWarningMsg
        || type == QtMsgType::QtCriticalMsg || type == QtMsgType::QtFatalMsg)
    {
        QString strLogMsg = QString("[DateTime:(%1) File:(%2:%3) Fun:(%4) ] %5: %6\n")
            .arg(strDateTime).arg(context.file).arg(context.line).arg(context.function)
            .arg(mapMsgType[type]).arg(msg);
        mutex.lock();
        listLogMsg.push_back(strLogMsg);
        mutex.unlock();
    }
}


void QBaseLog::run()
{
    while (isRunning)
    {
        QString file_name = QString("%1/%2%3").arg(logFilePath).arg(QDate::currentDate().toString("yyyy-MM-dd")).arg(QString(".log"));
        if (fileLog.fileName() != file_name || !fileLog.exists())
        {
            //关闭原来的文件
            fileLog.close();
            //打开新的文件
            fileLog.setFileName(file_name);
            if (!fileLog.open(QIODevice::WriteOnly | QIODevice::Append))
            {
                qDebug() << QStringLiteral("=======打开新日期日志文件失败=======");
            }
        }

        mutex.lock();
        if (fileLog.exists() && fileLog.isOpen() && !listLogMsg.isEmpty())
        {
            QString message = listLogMsg.front();
            listLogMsg.pop_front();
            fileLog.write(message.toUtf8());
            fileLog.flush();
        }
        mutex.unlock();

        msleep(100);
    }
}

